﻿using System;
using System.IO;
using System.Web;
using EPiServer.Framework;
using TemplateFoundation.Exceptions;
using TemplateFoundation.Reflection;

namespace TemplateFoundation.PageTypeIcons
{
    /// <summary>
    /// Responsible for ensuring a control adapter file exists required for page tree icons
    /// </summary>
    [InitializableModule]
    public class PageTypeIconsInitializableModule : IInitializableModule
    {
        #region IInitializableModule Members

        /// <summary>
        /// Creates control adapter file if it doesn't exist
        /// </summary>
        /// <param name="context"></param>
        public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
        {
            string adapterFilePath;

            if (HttpContext.Current==null) // For example if being initialized as part of a unit test or a Deployment Center upgrade
            {
                try
                {
                    // Get App_Browsers directory from project folder
                    var appBrowsersFolder = Directory.CreateDirectory(
                        Path.GetDirectoryName(
                        typeof(PageTypeIconsInitializableModule).Assembly.ManifestModule.FullyQualifiedName))
                        .Parent;

                    if (appBrowsersFolder==null)
                    {
                        return;
                    }

                    bool binDirectoryFound=false;

                    while (!binDirectoryFound)
                    {
                        if (appBrowsersFolder.Name.Equals("bin", StringComparison.OrdinalIgnoreCase))
                        {
                            binDirectoryFound = true;
                        }

                        appBrowsersFolder = appBrowsersFolder.Parent;
                    }

                    if (appBrowsersFolder==null)
                    {
                        return;
                    }

                    adapterFilePath = appBrowsersFolder.FullName + "\\App_Browsers\\PageTreeViewAdapter.browser";
                }
                catch
                {
                    // TODO Add logging, but we don't want to throw an exception since it breaks Deployment Center upgrades and this module isn't critical

                    return;
                }
            }
            else
            {
                // Get App_Browsers folder from the web application
                adapterFilePath = HttpContext.Current.Server.MapPath("/App_Browsers/PageTreeViewAdapter.browser");    
            }
            
            try
            {
                try
                {
                    // Get adapter file content from embedded resource
                    var adapterContent = EmbeddedResourceLoader.LoadTextFile("/App_Browsers/PageTreeViewAdapter.browser");

                    // Add ETF comment
                    if(string.IsNullOrEmpty(adapterContent))
                    {
                        throw new TemplateFoundationException("The embedded browser adapter content was empty");
                    }

                    adapterContent = adapterContent.Insert(0, "<!-- Adapter file added by EPiServer Template Foundation, do not modify -->\r\n");    

                    // Check if browser adapter file needs to be updated
                    if (File.Exists(adapterFilePath))
                    {
                        using (var fileReader = (TextReader) new StreamReader(File.Open(adapterFilePath, FileMode.Open)))
                        {
                            var fileContents = fileReader.ReadToEnd();

                            fileReader.Close();

                            if (fileContents == adapterContent)
                            {
                                // No update required
                                return;
                            }
                        }
                    }

                    if (string.IsNullOrEmpty(adapterContent))
                    {
                        throw new TemplateFoundationException("The embedded browser adapter file was empty");
                    }

                    // Ensure folder exists
                    Directory.CreateDirectory(Path.GetDirectoryName(adapterFilePath));

                    using (var fileWriter = File.CreateText(adapterFilePath))
                    {
                        fileWriter.Write(adapterContent);

                        fileWriter.Close();
                    }
                }
                catch (IOException ex)
                {
                    throw new TemplateFoundationException("Unable to write to control adapter file", ex);
                }
            }
            catch (IOException ex)
            {
                throw new TemplateFoundationException("Unable to create control adapter file", ex);
            }
        }

        /// <summary>
        /// Preload is not required
        /// </summary>
        /// <param name="parameters"></param>
        public virtual void Preload(string[] parameters)
        {

        }

        /// <summary>
        /// Uninitialization is not required
        /// </summary>
        /// <param name="context"></param>
        public virtual void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context)
        {

        }

        #endregion
    }
}
